package com.kgcx.dbutils.service;

import com.github.pagehelper.PageHelper;
import com.kgcx.common.constant.Cons;
import com.kgcx.common.utils.CollectionUtils;
import com.kgcx.common.utils.ReflectHelper;
import com.kgcx.dbutils.domain.Dict;
import com.kgcx.dbutils.mapper.DictMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

@Service
@ConditionalOnProperty(prefix = "kgcx.dbutils.dict", name = "enable", havingValue = "true")
@Slf4j
public class DictService {

    private static List<Dict> allDict;

    @Autowired
    private DictMapper dictMapper;

    /*public List<Dict> getDictByType(String type) {
        Dict dict = new Dict();
        dict.setType(type);
        return dictMapper.select(dict);
    }*/

    @Scheduled(cron = "0 0/30 * * * ?")   //每半小时一次
    public void reLoadAllDict() {
        PageHelper.orderBy("value asc");
        allDict = dictMapper.selectAllActive();
    }

    public List<Dict> getAllDict() {
        if (CollectionUtils.isEmpty(allDict)) {
            reLoadAllDict();
        }
        return allDict;
    }

    public Dict getDict(Long kid) {
        return dictMapper.selectByPrimaryKey(kid);
    }

    public List<Dict> getDictByType(String type) {
        List<Dict> dictList = getAllDict();
        if (StringUtils.isNotBlank(type)) {
            dictList = dictList.stream().filter(d -> d.getType().equals(type)).collect(Collectors.toList());
        }
        return dictList;
    }

    public Dict getDictByTypeAndName(String type, String name) {
        List<Dict> dictList = getAllDict();
        List<Dict> collect = dictList.stream().filter(d -> d.getType().equals(type)
                && d.getName().equals(name)).collect(Collectors.toList());
        return CollectionUtils.getFirst(collect);
    }

    public Dict getDictByTypeAndValue(String type, String value) {
        List<Dict> dictList = getAllDict();
        List<Dict> collect = dictList.stream().filter(d -> d.getType().equals(type)
                && d.getValue().equals(value)).collect(Collectors.toList());
        return CollectionUtils.getFirst(collect);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addDict(Dict dict) {
        dictMapper.insertSelective(dict);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateDict(Dict dict) {
        dictMapper.updateByPrimaryKeySelective(dict);
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeDict(Long kid) {
        Dict dict = new Dict();
        dict.setKid(kid);
        dict.setStatus(Cons.COMMON_STATUS_DELETE);
        dictMapper.updateByPrimaryKeySelective(dict);
    }

    /**
     * 根据实体属性的Dict注解,判断是否是字典的value字段,如果是则根据字典数据转换成对应的值
     * 比如 gender=1,而被@Dict注解的genderValue就会被自动注入值"男".
     *
     * @param data
     */
    public <T> T buildDictValue(T data) {
        if (null != data) {
            CollectionUtils.runOnObjectOrCollection(data, d -> {
                Field[] fields = d.getClass().getDeclaredFields();
                if (ArrayUtils.isNotEmpty(fields)) {
                    for (Field field : fields) {
                        com.kgcx.common.annotation.dict.Dict annotation = field.getAnnotation(com.kgcx.common.annotation.dict.Dict.class);
                        if (null != annotation) {
                            String fieldName = annotation.fieldName();
                            String type = annotation.type();
                            if (StringUtils.isNotBlank(type) && StringUtils.isNotBlank(fieldName)) {
                                Object valueObj = ReflectHelper.getFieldValue(d, fieldName);
                                if (null != valueObj) {
                                    String value = valueObj.toString();
                                    String[] split = value.split(",");
                                    if (ArrayUtils.isNotEmpty(split)) {
                                        StringBuilder finalValue = new StringBuilder();
                                        for (int i = 0; i < split.length; i++) {
                                            com.kgcx.dbutils.domain.Dict dictByTypeAndValue = getDictByTypeAndValue(type, split[i]);
                                            if (null != dictByTypeAndValue) {
                                                finalValue.append(dictByTypeAndValue.getName());
                                                if (i != split.length - 1) {
                                                    finalValue.append(",");
                                                }
                                            }
                                        }
                                        if (StringUtils.isNotBlank(finalValue.toString())) {
                                            ReflectHelper.setFieldValue(d, field.getName(), finalValue.toString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            });
        }
        return data;
    }
}
